package com.jinyou.utils.common;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 不同对象间的的赋值
 *
 * @author Jahnke 2016年5月28日 16:34:30
 */
public class ObjectUtils {

    /**
     * 复制对象属性
     *
     * @param from
     * @param to
     * @param excludsArray 排除属性列表
     * @throws Exception
     */
    public static void copyPropertiesExclude(Object from, Object to, String[] excludsArray) throws Exception {
        List<String> excludesList = null;
        if (excludsArray != null && excludsArray.length > 0) {
            excludesList = Arrays.asList(excludsArray); //构造列表对象  
        }
        Method[] fromMethods = from.getClass().getDeclaredMethods();
        Method[] toMethods = to.getClass().getDeclaredMethods();
        Method fromMethod = null, toMethod = null;
        String fromMethodName = null, toMethodName = null;
        for (int i = 0; i < fromMethods.length; i++) {
            fromMethod = fromMethods[i];
            fromMethodName = fromMethod.getName();
            if (!fromMethodName.contains("get"))
                continue;
            //排除列表检测  
            if (excludesList != null && excludesList.contains(fromMethodName.substring(3).toLowerCase())) {
                continue;
            }
            toMethodName = "set" + fromMethodName.substring(3);
            toMethod = findMethodByName(toMethods, toMethodName);
            if (toMethod == null)
                continue;
            Object value = fromMethod.invoke(from, new Object[0]);
            if (value == null)
                continue;
            //集合类判空处理  
            if (value instanceof Collection) {
                Collection newValue = (Collection) value;
                if (newValue.size() <= 0)
                    continue;
            }
            toMethod.invoke(to, new Object[]{value});
        }
    }

    /**
     * 复制对象属性
     *
     * @param from
     * @param to
     * @throws Exception
     */
    public static void copyPropertiesExclude(Object from, Object to) throws Exception {
        copyPropertiesExclude(from, to, null);
    }


    /**
     * 从方法数组中获取指定名称的方法
     *
     * @param methods
     * @param name
     * @return
     */
    public static Method findMethodByName(Method[] methods, String name) {
        for (int j = 0; j < methods.length; j++) {
            if (methods[j].getName().equals(name))
                return methods[j];
        }
        return null;
    }

    /**
     * 将对象转成map
     *
     * @param obj
     * @return
     */
    public static Map<String, Object> beanToMap(Object obj) {
        if (obj != null) {
            Map<String, Object> map = new HashMap<String, Object>();
            BeanInfo beanInfo;
            try {
                beanInfo = Introspector.getBeanInfo(obj.getClass());
                PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
                for (PropertyDescriptor property : propertyDescriptors) {
                    String key = property.getName();
                    if (key.compareToIgnoreCase("class") == 0) {
                        continue;
                    }
                    Method getter = property.getReadMethod();
                    Object value = getter != null ? getter.invoke(obj) : "";
                    map.put(key, value);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return map;
        } else {
            return null;
        }
    }

    public static List<HashMap<String, Object>> beanToHashMap(List<Object> objs) {
        if (objs != null && objs.size() > 0) {
            List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
            for (int i = 0; i < objs.size(); i++) {
                Object obj = objs.get(i);
                if (obj != null) {
                    HashMap<String, Object> map = new HashMap<String, Object>();
                    BeanInfo beanInfo;
                    try {
                        beanInfo = Introspector.getBeanInfo(obj.getClass());
                        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
                        for (PropertyDescriptor property : propertyDescriptors) {
                            String key = property.getName();
                            if (key.compareToIgnoreCase("class") == 0) {
                                continue;
                            }
                            Method getter = property.getReadMethod();
                            Object value = getter != null ? getter.invoke(obj) : null;
                            map.put(key, value);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    list.add(map);
                } else {
                    return null;
                }
            }
            return list;
        } else {
            return null;
        }
    }
    //java 反射 通过属性名获取私有属性值
    public static String getFieldValueByFieldName(String fieldName, Object object) {
        try {
            if(null == object){
                return null;
            }
            Field field = object.getClass().getDeclaredField(fieldName);
            //设置对象对私有属性的访问权限
            field.setAccessible(true);
            return (String)field.get(object);
        } catch (Exception e) {
            return null;
        }
    }
}
